package meta.api.web.data.presentation;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import meta.api.web.account.businessinfo.UserInfo;
import meta.api.web.common.util.ApiConst;
import meta.api.web.common.util.ApiUtil;
import meta.api.web.data.businesscontrol.DataMngBusiCtrl;
import meta.api.web.data.presentation.form.DataForm;
import meta.api.web.data.presentation.form.DataListResult;
import meta.api.web.data.presentation.form.FolderForm;
import meta.api.web.data.presentation.form.FolderInfo;
import meta.api.web.data.presentation.form.FolderListForm;
import meta.api.web.data.presentation.form.FolderListResult;
import meta.api.web.directory.businessinfo.DirInfo;
import meta.common.log.CmnLogger;
import meta.common.msg.MessageConst;
import meta.common.util.JsonUtil;
import meta.common.util.ListUtil;
import meta.common.util.StrUtil;
import meta.common.util.WebUtil;

@Controller
@RequestMapping(value="api/data")
@Tag(name = "数据管理机能", description = "数据管理机能")
public class DataMngController {

    private static final CmnLogger logger = CmnLogger.getLogger(DataMngController.class);

    private static final String FUNC_NM = "数据管理机能";

    private static final String ERROR_MSG_DATA_ERROR= "请求数据错误";
    private static final String ERROR_MSG_GET_LIST_ERROR= "获取数据列表失败";
    private static final String ERROR_MSG_SAVE_ERROR= "保存数据失败";
    private static final String ERROR_MSG_UPDATE_ERROR= "更新数据失败";
    private static final String ERROR_MSG_GET_ERROR= "获取数据失败";
    private static final String ERROR_MSG_DELETE_ERROR= "删除数据失败";
    private static final String ERROR_MSG_EXISTED_FOLDER_ERROR= "文件夹已经存在";
    private static final String ERROR_MSG_SAVE_FOLDER_ERROR= "保存文件夹失败";
    private static final String ERROR_MSG_UPDATE_FOLDER_ERROR= "更新文件夹失败";
    private static final String ERROR_MSG_GET_FOLDER_ERROR= "获取文件夹失败";
    private static final String ERROR_MSG_DELETE_FOLDER_ERROR= "删除文件夹失败";

    @Autowired
    private DataMngBusiCtrl dataMngBusiCtrl;

    /**
     * 获取图纸/自定义组件/在线图片列表
     * 
     * @param req 请求
     * @param res 响应
     * @param collection 收藏分类
     * @param current 当前页
     * @param pageSize 每页记录数
     * @return
     * @throws Exception 异常
     */
    @SuppressWarnings("unchecked")
    @PostMapping(value="/{collection}/list")
    @Operation(tags = "获取图纸/自定义组件/在线图片列表", description = "获取图纸/自定义组件/在线图片列表")
    public String list(HttpServletRequest req, HttpServletResponse res,
            @PathVariable("collection") String collection,
            @RequestParam(value = "current", required = false) Integer current,
            @RequestParam(value = "pageSize", required = false) Integer pageSize) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "获取图纸/自定义组件/在线图片列表", null);

        FolderListForm inputdata = JsonUtil.toObj(ApiUtil.readTxtBody(req), FolderListForm.class);

        String type = null;
        String folder = null;
        String tags = null;
        LinkedHashMap<String, Integer> projectionMap = null;
        Boolean projectionIncludeFlag = null;
        if (inputdata != null && inputdata.getQuery() != null) {
            if (StrUtil.isNotEmpty(inputdata.getQuery().getType())) {
                type = inputdata.getQuery().getType();
            }
            folder = inputdata.getQuery().getFolder();
            if (StrUtil.isNotEmpty(inputdata.getQuery().getTags())) {
                tags = inputdata.getQuery().getTags();
            }
            if (inputdata.getProjection() != null) {
                projectionMap = (LinkedHashMap<String, Integer>) inputdata.getProjection();
                try {
                    projectionIncludeFlag = checkProjection(projectionMap);
                } catch (Exception e) {
                    ApiUtil.setErrorJsonResponse(res, e.getMessage());
                    return null;
                }
                if (projectionIncludeFlag == null) {
                    projectionMap = null;
                }
            }
        }

        // 重置{collection}
        collection = resetCollection(collection, Arrays.asList(tags));
        if (collection == null) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
        }

        int total;
        List<String> dataList = new ArrayList<String>();
        try {
            // 取得登录用户详细情报
            UserInfo loginUser = WebUtil.getLoginUser(req);

            // 获取数据总件数
            total = dataMngBusiCtrl.getDataTotal(
                    loginUser.getId(), collection, type, folder);

            // 获取数据列表
            if (total > 0) {
                dataList = dataMngBusiCtrl.getDataList(
                        loginUser.getId(), collection, type, folder,
                        projectionMap, projectionIncludeFlag,
                        current, pageSize);
            }

            DataListResult result = new DataListResult();
            result.setTotal(total);
            result.setList(dataList);

            ApiUtil.setJsonResponse(res, result.buildJsonResult());
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_GET_LIST_ERROR);
        }

        return null;
    }

    /**
     * 新增图纸/自定义组件/在线图片
     * 
     * @param req 请求
     * @param res 响应
     * @param collection 收藏分类
     * @return
     * @throws Exception 异常
     */
    @PostMapping(value="/{collection}/add")
    @Operation(tags = "新增图纸/自定义组件/在线图片", description = "新增图纸/自定义组件/在线图片")
    public String add(HttpServletRequest req, HttpServletResponse res,
            @PathVariable("collection") String collection) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "新增图纸/自定义组件/在线图片", null);

        String inputData = ApiUtil.readTxtBody(req);

        // 重置{collection}
        Object tags = ApiUtil.getKeyObjVal(inputData, "tags");
        List<String> tagList = JsonUtil.toListObj(JsonUtil.toJsonStr(tags), String.class);
        collection = resetCollection(collection, tagList);
        if (collection == null) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        // 取得登录用户详细情报
        UserInfo loginUser = WebUtil.getLoginUser(req);

        // 保存数据(图纸/自定义组件/在线图片)
        // ID
        Long id = null;
        try {
            // 生成ID
            id = dataMngBusiCtrl.getSeqNextVal("seq_re_data_id");
            String owner = ApiUtil.buildUserJsonStr(req, true);
            String editor = ApiUtil.buildUserJsonStr(req, false);
            dataMngBusiCtrl.saveData(
                    String.valueOf(id), loginUser.getId(), collection,
                    inputData, owner, editor);
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_SAVE_ERROR);
            return null;
        }

        // 获取数据(图纸/自定义组件/在线图片)
        String data = null;
        try {
            data = dataMngBusiCtrl.getData(String.valueOf(id), loginUser.getId(), null, null);
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_GET_ERROR);
            return null;
        }

        if (data == null) {
            ApiUtil.setNotFoundResponse(req, res);
        } else {
            ApiUtil.setJsonResponse(res, data);
        }
        return null;
    }

    /**
     * 更新图纸/自定义组件
     * 
     * @param req 请求
     * @param res 响应
     * @param collection 收藏分类
     * @return
     * @throws Exception 异常
     */
    @PostMapping(value="/{collection}/update")
    @Operation(tags = "更新图纸/自定义组件", description = "更新图纸/自定义组件")
    public String update(HttpServletRequest req, HttpServletResponse res,
            @PathVariable("collection") String collection) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "更新图纸/自定义组件", null);

        String inputData = ApiUtil.readTxtBody(req);

        // 获取ID
        String id = ApiUtil.getKeyStrVal(inputData, "_id");
        if (StrUtil.isEmpty(id)) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        // 取得登录用户详细情报
        UserInfo loginUser = WebUtil.getLoginUser(req);

        // 权限检证
        if (!dataMngBusiCtrl.checkIsDataOwner(id, loginUser.getId())) {
            ApiUtil.setForbiddenResponse(req, res);
            return null;
        }

        // 更新数据(图纸/自定义组件)
        try {
            String editor = ApiUtil.buildUserJsonStr(req, false);
            dataMngBusiCtrl.updateData(id, loginUser.getId(), inputData, editor);
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_UPDATE_ERROR);
            return null;
        }

        // 获取数据(图纸/自定义组件)
        String data = null;
        try {
            data = dataMngBusiCtrl.getData(id, loginUser.getId(), null, null);
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_GET_ERROR);
            return null;
        }

        if (data == null) {
            ApiUtil.setNotFoundResponse(req, res);
        } else {
            ApiUtil.setJsonResponse(res, data);
        }
        return null;
    }

    /**
     * 获取图纸/自定义组件
     * 
     * @param req 请求
     * @param res 响应
     * @param collection 收藏分类
     * @return
     * @throws Exception 异常
     */
    @SuppressWarnings("unchecked")
    @PostMapping(value="/{collection}/get")
    @Operation(tags = "获取图纸/自定义组件", description = "获取图纸/自定义组件")
    public String get(HttpServletRequest req, HttpServletResponse res,
            @PathVariable("collection") String collection) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "获取图纸/自定义组件", null);

        DataForm inputdata = JsonUtil.toObj(ApiUtil.readTxtBody(req), DataForm.class);
        if (inputdata == null
                || StrUtil.isEmpty(inputdata.getId())) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        LinkedHashMap<String, Integer> projectionMap = null;
        Boolean projectionIncludeFlag = null;
        if (inputdata.getProjection() != null) {
            projectionMap = (LinkedHashMap<String, Integer>) inputdata.getProjection();
            try {
                projectionIncludeFlag = checkProjection(projectionMap);
            } catch (Exception e) {
                ApiUtil.setErrorJsonResponse(res, e.getMessage());
                return null;
            }
            if (projectionIncludeFlag == null) {
                projectionMap = null;
            }
        }

        // 取得登录用户详细情报
        UserInfo loginUser = WebUtil.getLoginUser(req);

        // 获取数据(图纸/自定义组件)
        String data = null;
        try {
            data = dataMngBusiCtrl.getData(inputdata.getId(), loginUser.getId(),
                    projectionMap, projectionIncludeFlag);
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_GET_ERROR);
            return null;
        }

        if (data == null) {
            ApiUtil.setNotFoundResponse(req, res);
        } else {
            ApiUtil.setJsonResponse(res, data);
        }
        return null;
    }

    /**
     * 删除图纸/自定义组件/在线图片
     * 
     * @param req 请求
     * @param res 响应
     * @param collection 收藏分类
     * @return
     * @throws Exception 异常
     */
    @PostMapping(value="/{collection}/delete")
    @Operation(tags = "删除图纸/自定义组件/在线图片", description = "删除图纸/自定义组件/在线图片")
    public String delete(HttpServletRequest req, HttpServletResponse res,
            @PathVariable("collection") String collection) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "删除图纸/自定义组件/在线图片", null);

        DataForm inputdata = JsonUtil.toObj(ApiUtil.readTxtBody(req), DataForm.class);
        if (inputdata == null
                || StrUtil.isEmpty(inputdata.getId())) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        // 取得登录用户详细情报
        UserInfo loginUser = WebUtil.getLoginUser(req);

        // 权限检证
        if (!dataMngBusiCtrl.checkIsDataOwner(inputdata.getId(), loginUser.getId())) {
            ApiUtil.setForbiddenResponse(req, res);
            return null;
        }

        // 删除数据(图纸/自定义组件/在线图片)
        try {
            dataMngBusiCtrl.deleteData(inputdata.getId(), loginUser.getId());
            ApiUtil.setEmptyJsonResponse(res);
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DELETE_ERROR);
        }

        return null;
    }

    /**
     * 获取(图纸)文件夹列表
     * 
     * @param req 请求
     * @param res 响应
     * @return
     * @throws Exception 异常
     */
    @PostMapping(value="/folders/list")
    @Operation(tags = "获取(图纸)文件夹列表", description = "获取(图纸)文件夹列表")
    public String folderList(HttpServletRequest req, HttpServletResponse res) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "获取(图纸)文件夹列表", null);

        FolderListForm inputdata = JsonUtil.toObj(ApiUtil.readTxtBody(req), FolderListForm.class);
        if (inputdata == null
                || inputdata.getQuery() == null
                || StrUtil.isEmpty(inputdata.getQuery().getType())) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        int total = 0;
        List<FolderInfo> folderList = new ArrayList<FolderInfo>();
        try {
            // 取得登录用户详细情报
            UserInfo loginUser = WebUtil.getLoginUser(req);

            // 获取文件夹总件数
            total = dataMngBusiCtrl.getFolderListTotal(loginUser.getId(), inputdata.getQuery().getType());

            // 获取文件夹列表
            if (total > 0) {
                folderList = dataMngBusiCtrl.getFolderList(loginUser.getId(), inputdata.getQuery().getType());
            }
        } catch (Exception e) {
            total = 0;
            logger.log(MessageConst.MSG_01090001, null, e);
        }

        FolderListResult result = new FolderListResult();
        result.setTotal(total);
        result.setList(folderList);

        ApiUtil.setJsonResponse(res, result.buildJsonResult());
        return null;
    }

    /**
     * 添加(图纸)文件夹
     * 
     * @param req 请求
     * @param res 响应
     * @return
     * @throws Exception 异常
     */
    @PostMapping(value="/folders/add")
    @Operation(tags = "添加(图纸)文件夹", description = "添加(图纸)文件夹")
    public String folderAdd(HttpServletRequest req, HttpServletResponse res) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "添加(图纸)文件夹", null);

        FolderForm inputdata = JsonUtil.toObj(ApiUtil.readTxtBody(req), FolderForm.class);
        if (inputdata == null
                || StrUtil.isEmpty(inputdata.getType())
                || StrUtil.isEmpty(inputdata.getName())) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        // 取得登录用户详细情报
        UserInfo loginUser = WebUtil.getLoginUser(req);

        // 检证是否已经存在文件夹
        if (dataMngBusiCtrl.checkExistFolder(loginUser.getId(), inputdata.getType(), inputdata.getName())) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_EXISTED_FOLDER_ERROR);
            return null;
        }

        // 添加文件夹
        try {
            dataMngBusiCtrl.addFolder(loginUser.getId(), inputdata.getType(), inputdata.getName());
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_SAVE_FOLDER_ERROR);
            return null;
        }

        // 获取文件夹
        FolderInfo folder = null;
        try {
            folder = dataMngBusiCtrl.getFolder(loginUser.getId(), inputdata.getType(), inputdata.getName());
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_GET_FOLDER_ERROR);
            return null;
        }

        if (folder == null) {
            ApiUtil.setNotFoundResponse(req, res);
        } else {
            ApiUtil.setJsonResponse(res, folder.buildJsonResult());
        }
        return null;
    }

    /**
     * 更新(图纸)文件夹
     * 
     * @param req 请求
     * @param res 响应
     * @return
     * @throws Exception 异常
     */
    @PostMapping(value="/folders/update")
    @Operation(tags = "更新(图纸)文件夹", description = "更新(图纸)文件夹")
    public String folderUpdate(HttpServletRequest req, HttpServletResponse res) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "更新(图纸)文件夹", null);

        FolderForm inputdata = JsonUtil.toObj(ApiUtil.readTxtBody(req), FolderForm.class);
        if (inputdata == null
                || StrUtil.isEmpty(inputdata.getId())) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        String newFolderName = inputdata.getName();

        // 取得登录用户详细情报
        UserInfo loginUser = WebUtil.getLoginUser(req);

        // 权限检证
        if (!dataMngBusiCtrl.checkIsDirOwner(inputdata.getId(), loginUser.getId())) {
            ApiUtil.setForbiddenResponse(req, res);
            return null;
        }

        // 获取文件夹信息
        DirInfo dir = dataMngBusiCtrl.getDir(inputdata.getId(), loginUser.getId());
        if (dir == null) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_GET_FOLDER_ERROR);
            return null;
        }

        // 更新文件夹
        try {
            String editor = ApiUtil.buildUserJsonStr(req, false);
            dataMngBusiCtrl.updateFolder(
                    loginUser.getId(), dir.getType(),
                    dir.getFullpath(), newFolderName,
                    inputdata.getList(), editor);
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_UPDATE_FOLDER_ERROR);
            return null;
        }

        // 获取文件夹
        FolderInfo folder = null;
        try {
            folder = dataMngBusiCtrl.getFolder(
                    loginUser.getId(), dir.getType(),
                    StrUtil.isNotEmpty(newFolderName) ? newFolderName : dir.getFullpath());
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_GET_FOLDER_ERROR);
            return null;
        }

        if (folder == null) {
            ApiUtil.setNotFoundResponse(req, res);
        } else {
            ApiUtil.setJsonResponse(res, folder.buildJsonResult());
        }
        return null;
    }

    /**
     * 获取(图纸)文件夹
     * 
     * @param req 请求
     * @param res 响应
     * @return
     * @throws Exception 异常
     */
    @PostMapping(value="/folders/get")
    @Operation(tags = "获取(图纸)文件夹", description = "获取(图纸)文件夹")
    public String folderGet(HttpServletRequest req, HttpServletResponse res) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "获取(图纸)文件夹", null);

        FolderListForm inputdata = JsonUtil.toObj(ApiUtil.readTxtBody(req), FolderListForm.class);
        if (inputdata == null
                || inputdata.getQuery() == null
                || StrUtil.isEmpty(inputdata.getQuery().getType())
                || StrUtil.isEmpty(inputdata.getQuery().getName())) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        // 取得登录用户详细情报
        UserInfo loginUser = WebUtil.getLoginUser(req);

        // 获取文件夹
        FolderInfo folder = null;
        try {
            folder = dataMngBusiCtrl.getFolder(
                    loginUser.getId(),
                    inputdata.getQuery().getType(),
                    inputdata.getQuery().getName());
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_GET_FOLDER_ERROR);
            return null;
        }

        if (folder == null) {
            ApiUtil.setNotFoundResponse(req, res);
        } else {
            ApiUtil.setJsonResponse(res, folder.buildJsonResult());
        }
        return null;
    }

    /**
     * 删除(图纸)文件夹
     * 
     * @param req 请求
     * @param res 响应
     * @return
     * @throws Exception 异常
     */
    @PostMapping(value="/folders/delete")
    @Operation(tags = "删除(图纸)文件夹", description = "删除(图纸)文件夹")
    public String folderDelete(HttpServletRequest req, HttpServletResponse res) throws Exception {
        ApiUtil.callApiLog(req, FUNC_NM, "删除(图纸)文件夹", null);

        String inputData = ApiUtil.readTxtBody(req);

        // 获取ID
        String id = ApiUtil.getKeyStrVal(inputData, "id");
        if (StrUtil.isEmpty(id)) {
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DATA_ERROR);
            return null;
        }

        // 取得登录用户详细情报
        UserInfo loginUser = WebUtil.getLoginUser(req);

        // 权限检证
        if (!dataMngBusiCtrl.checkIsDirOwner(id, loginUser.getId())) {
            ApiUtil.setForbiddenResponse(req, res);
            return null;
        }

        // 删除文件夹
        try {
            dataMngBusiCtrl.deleteFolder(id, loginUser.getId());
            ApiUtil.setJsonResponse(res, inputData);
        } catch (Exception e) {
            logger.log(MessageConst.MSG_01090001, null, e);
            ApiUtil.setErrorJsonResponse(res, ERROR_MSG_DELETE_FOLDER_ERROR);
        }

        return null;
    }

    private Boolean checkProjection(LinkedHashMap<String, Integer> projectionMap) throws Exception {
        if (projectionMap == null || projectionMap.isEmpty()) {
            return null;
        }
        if (projectionMap.containsValue(0) && projectionMap.containsValue(1)) {
            throw new Exception(ERROR_MSG_DATA_ERROR);
        }
        if (!projectionMap.containsValue(0) && !projectionMap.containsValue(1)) {
            throw new Exception(ERROR_MSG_DATA_ERROR);
        }
        for (Map.Entry<String, Integer> entry : projectionMap.entrySet()) {
            Integer value = entry.getValue();
            if (!value.equals(0) && !value.equals(1)) {
                throw new Exception(ERROR_MSG_DATA_ERROR);
            }
        }
        if (projectionMap.containsValue(0)) {
            return Boolean.FALSE;
        } else {
            return Boolean.TRUE;
        }
    }

    private String resetCollection(String collection, List<String> tags) {
        if (StrUtil.isNotEmpty(collection) && !collection.equals(ApiConst.V_COLL_TYPE_PROJ)) {
            return collection;
        }
        if (ListUtil.isEmptyList(tags)) {
            return collection;
        }
        if (tags.contains(ApiConst.V_TAG_TYPE_PROJ)) {
            return ApiConst.V_COLL_TYPE_PROJ;
        } else if (tags.contains(ApiConst.V_TAG_TYPE_TMPL)) {
            return ApiConst.V_COLL_TYPE_TMPL;
        } else {
            return collection;
        }
    }
}
